﻿using System.Data;
using System.Text;
using Dapper;
using Md.Api.Entity.DapperModels.MdDB;

namespace Md.Dapper.Repositories;
/// <summary>
/// 仓储基类
/// </summary>
/// <typeparam name="T">实体对象</typeparam>
public class BaseRep<T> : IBaseRep<T> where T : new()
{
    /// <summary>
    /// 实体
    /// </summary>
    public T model { get; set; } = new T();

    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="model">实体</param>
    /// <returns>int</returns>
    public int Insert(T model)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            var tableName = GetTableName();

            var modelInstance = GetTableFields();

            var fields = string.Join(",", modelInstance.Select(s => s.Key).ToList());

            var values = string.Join(",", modelInstance.Select(s => $"@{s.Value}").ToList());

            #region ===sql===
            string sqlStr = string.Format(@"insert into {0} ({1}) values({2})", tableName, fields, values);
            #endregion

            var res = conn.Execute(sqlStr, model);

            if (res > 0)
            {
                return Convert.ToInt32(conn.ExecuteScalar("select LAST_INSERT_ID()"));
            }
            else
            {
                return res;
            }
        }
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="sqlWhere">查询</param>
    /// <param name="model">实体</param>
    /// <returns>int</returns>
    public int Delete(string sqlWhere, object model)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            var tableName = GetTableName();

            string sqlStr = string.Format(@"delete from {0} where 1 = 1 {1}", tableName, sqlWhere);

            return conn.Execute(sqlStr, model);
        }
    }

    /// <summary>
    /// 更新
    /// </summary>
    /// <param name="sqlSet">set字段</param>
    /// <param name="sqlWhere">查询</param>
    /// <param name="model">实体</param>
    /// <returns>int</returns>
    public int Update(string sqlSet, string sqlWhere, object model)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            var tableName = GetTableName();

            var sqlStr = new StringBuilder();

            sqlStr.Append(string.Format(@" update {0} set ", tableName));

            sqlStr.Append(sqlSet);

            sqlStr.Append(string.Format(@" where 1 = 1 {0} ", sqlWhere));

            return conn.Execute(sqlStr.ToString(), model);
        }
    }

    /// <summary>
    /// 查询一条数据
    /// </summary>
    /// <param name="sqlFields">字段</param>
    /// <param name="sqlWhere">查询</param>
    /// <param name="model">实体</param>
    /// <returns>T?</returns>
    public T? QuerySingle(string sqlFields, string sqlWhere, object model)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            var tableName = GetTableName();

            string sqlStr = string.Format(@"select {0} from {1} where 1 = 1 {2} limit 1", sqlFields, tableName, sqlWhere);

            var res = conn.QueryFirstOrDefault<T?>(sqlStr, model);

            return res;
        }
    }

    /// <summary>
    /// 查询一条数据
    /// </summary>
    /// <param name="sqlFields">字段</param>
    /// <param name="model">实体</param>
    /// <returns>T?</returns>
    public T? QuerySingle(string sql, object model)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            var res = conn.QueryFirstOrDefault<T>(sql, model);

            return res;
        }
    }

    /// <summary>
    /// 查询总条数
    /// </summary>
    /// <param name="sqlFields">字段</param>
    /// <param name="model">实体</param>
    /// <returns>int</returns>
    public int QueryCount(string sql, object model)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            var res = conn.ExecuteScalar(sql, model);

            return Convert.ToInt32(res);
        }
    }

    /// <summary>
    /// 查询数据
    /// </summary>
    /// <param name="sql">sql字符串</param>
    /// <param name="model">实体对象</param>
    /// <returns>IEnumerable<T></returns>
    public IEnumerable<T> Query(string sql, object model)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            var res = conn.Query<T>(sql, model);

            return res;
        }
    }

    /// <summary>
    /// 查询列表数据
    /// </summary>
    /// <param name="sqlFields">字段</param>
    /// <param name="sqlWhere">查询</param>
    /// <param name="model">实体</param>
    /// <returns>IEnumerable<T></returns>
    public IEnumerable<T> QueryList(string sqlFields, string sqlWhere, object model)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            var tableName = GetTableName();

            string sqlStr = string.Format(@"select {0} from {1} where 1 = 1 {2}", sqlFields, tableName, sqlWhere);

            var res = conn.Query<T>(sqlStr, model);

            return res;
        }
    }

    /// <summary>
    /// 查询分页列表数据
    /// </summary>
    /// <param name="sqlFields">字段</param>
    /// <param name="sqlWhere">查询</param>
    /// <param name="model">实体（匿名类型 new {}）</param>
    /// <param name="pageIndex">当前页</param>
    /// <param name="pageSize">每页条数</param>
    /// <returns>IEnumerable<T></returns>
    public Page<T> QueryPage(string sqlFields, string sqlWhere, object model, int pageIndex,int pageSize)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            // 重新计算当前页
            pageIndex = (pageIndex - 1) * pageSize;

            var tableName = GetTableName();

            string sqlStr = string.Format(@"select {0} from {1} where 1 = 1 {2} limit {3},{4}", sqlFields, tableName, sqlWhere, pageIndex, pageSize);

            var res = conn.Query<T>(sqlStr, model);

            string sqlCountStr = string.Format(@"select count(*) from {0} where 1 = 1 {1} limit 1", tableName, sqlWhere);

            var countRes = conn.ExecuteScalar(sqlCountStr, model);

            var page = new Page<T>();

            page.Items = res.ToList();
            page.TotalItems = Convert.ToInt32(countRes);
            page.CurrentPage = pageIndex;
            page.PageSize = pageSize;
            page.TotalPages = (int)Math.Ceiling(page.TotalItems / (double)page.PageSize);

            return page;
        }
    }

    /// <summary>
    /// 返回第一行第一列
    /// </summary>
    /// <param name="sqlField">字段(单个字段)</param>
    /// <param name="sqlWhere">查询</param>
    /// <param name="model">实体</param>
    /// <returns>object?</returns>
    public object? Scalar(string sqlField, string sqlWhere, object model)
    {
        using (IDbConnection conn = DataBaseConfig.GetSqlConnection())
        {
            var tableName = GetTableName();

            string sqlStr = string.Format(@"select {0} from {1} where 1 = 1 {2} limit 1", sqlField, tableName, sqlWhere);

            return conn.ExecuteScalar(sqlStr, model);
        }
    }

    /// <summary>
    /// 获取排序
    /// </summary>
    /// <param name="orderBy">要排序的字段</param>
    /// <param name="isDesc">是否降序</param>
    /// <returns>string</returns>
    public string GetOrderByDesc(string orderBy, bool isDesc)
    {
        string orderByParams = string.Empty;


        if (string.IsNullOrWhiteSpace(orderBy))
        {
            orderByParams += " create_time ";
        }
        else
        {
            orderByParams += $" {orderBy} ";
        }

        if (isDesc)
        {
            orderByParams += " desc ";
        }

        if (!isDesc)
        {
            orderByParams += " asc ";
        }

        string strOrderBy = string.Format(@" order by {0} ", orderByParams);

        return strOrderBy;
    }

    /// <summary>
    /// 获取表明
    /// </summary>
    /// <param name="model">实体对象</param>
    /// <returns>object</returns>
    public object GetTableName()
    {
        object tableName = "";

        if (model != null)
        {
            // 获取表名
            var modelCustomAttributes = model.GetType().CustomAttributes.Where(s => s.AttributeType.Name == "TableAttribute").FirstOrDefault();

            if (modelCustomAttributes != null)
            {
                var dbTableName = modelCustomAttributes.ConstructorArguments.FirstOrDefault().Value;

                if (dbTableName != null)
                {
                    tableName = dbTableName ?? "";
                }
            }
        }

        return tableName;
    }
    /// <summary>
    /// 获取表字段
    /// </summary>
    /// <param name="model">实体对象</param>
    /// <returns>Dictionary<object, string></returns>
    public Dictionary<object, string> GetTableFields()
    {
        var fieldDic = new Dictionary<object, string>();

        if (model != null)
        {
            var properties = model.GetType().GetProperties();

            foreach (var info in properties)
            {
                var customAttributes = info.CustomAttributes.Where(s => s.AttributeType.Name == "ColumnAttribute").FirstOrDefault();

                var isCustom = info.CustomAttributes.Where(s => s.NamedArguments.Where(w => w.TypedValue.Value?.ToString() == "custom").ToList().Count > 0).FirstOrDefault();

                if (customAttributes != null && isCustom == null)
                {
                    var dbField = customAttributes.ConstructorArguments.FirstOrDefault().Value;

                    if (dbField != null)
                    {
                        fieldDic.Add(dbField ?? "", info.Name);
                    }
                }
            }
        }

        return fieldDic;
    }
}